package com.zxjbyte.yiyi.framework.common.domain.mail;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;

import javax.activation.DataSource;
import java.io.File;
import java.io.InputStream;
import java.util.List;

/**
 * @Author zhangxingjia
 * @Date 2023/6/5 18:13
 * @Version: 1.0
 */
@Getter
@Setter
public class MailAttachmentMetadata extends MailMetadata{

    // 多附件
    private List<Attachment> attachmentList;

    public MailAttachmentMetadata(String from, String subject, String text){
        super(from, subject, text);
    }

    @Data
    public static class Attachment{
        // 附件名字
        private String attachmentFilename;

        // 附件文件
        private File file;

        // 输入流
        private InputStream inputStream;

        // 内容bytes
        private byte[] contentBytes;

        // 数据源对象，表示附件的数据来源。可以使用 Spring 的 DataSource 接口的实现类，例如 ByteArrayDataSource、FileDataSource 等
        private DataSource dataSource;
    }

    public static MailAttachmentMetadata of(String from, String[] to, String subject,
                                  String text, String attachmentFilename, File file){
        MailAttachmentMetadata metadata = new MailAttachmentMetadata(from, subject, text);
        metadata.setTo(to);
        // 添加附件
        Attachment attachment = new Attachment();
        attachment.setAttachmentFilename(checkAttachmentFilename(attachmentFilename));
        attachment.setFile(file);
        metadata.setAttachmentList(ImmutableList.of(attachment));
        return metadata;
    }

    public static MailAttachmentMetadata of(String from, String[] to, String subject,
                                  String text, String attachmentFilename, InputStream inputStream){
        MailAttachmentMetadata metadata = new MailAttachmentMetadata(from, subject, text);
        metadata.setTo(to);

        // 添加附件
        Attachment attachment = new Attachment();
        attachment.setAttachmentFilename(checkAttachmentFilename(attachmentFilename));
        attachment.setInputStream(inputStream);
        metadata.setAttachmentList(ImmutableList.of(attachment));
        return metadata;
    }

    public static MailAttachmentMetadata of(String from, String[] to, String subject,
                                  String text, String attachmentFilename, byte[] contentBytes){
        MailAttachmentMetadata metadata = new MailAttachmentMetadata(from, subject, text);
        metadata.setTo(to);

        // 添加附件
        Attachment attachment = new Attachment();
        attachment.setAttachmentFilename(checkAttachmentFilename(attachmentFilename));
        attachment.setContentBytes(contentBytes);
        metadata.setAttachmentList(ImmutableList.of(attachment));
        return metadata;
    }

    public static MailAttachmentMetadata of(String from, Object to, Object cc, Object bcc, String subject,
                                  String text, List<Attachment> attachmentList){
        MailAttachmentMetadata metadata = new MailAttachmentMetadata(from, subject, text);
        metadata.setTo(object2StrArr(to));
        metadata.setCc(object2StrArr(cc));
        metadata.setBcc(object2StrArr(bcc));

        // 添加附件
        metadata.setAttachmentList(attachmentList);
        return metadata;
    }

    public static MailAttachmentMetadata of(String from, Object to, Object cc, Object bcc, String subject,
                                  String text, Object[] attachmentArr){
        Assert.isTrue(attachmentArr.length % 2 == 0, "Array length is not a multiple of 2");
        // 多附件格式 {"附件名字", 附件, "附件名字", 附件}
        List<Attachment> attachmentList = Lists.newArrayList();
        for (int i = 0; i < attachmentArr.length; i += 2) {
            String attachmentFilename = checkAttachmentFilename(Convert.toStr(attachmentArr[i]));
            Object attachmentObj = attachmentArr[i + 1];
            Attachment attachment = new Attachment();
            attachment.setAttachmentFilename(attachmentFilename);
            if(attachmentObj instanceof File){
                attachment.setFile((File) attachmentObj);
            } else if(attachmentObj instanceof InputStream){
                attachment.setInputStream((InputStream) attachmentObj);
            } else if(attachmentObj instanceof byte[]) {
                attachment.setContentBytes((byte[]) attachmentObj);
            } else if(attachmentObj instanceof DataSource) {
                attachment.setDataSource((DataSource) attachmentObj);
            }
            attachmentList.add(attachment);
        }
        return MailAttachmentMetadata.of(from, to, cc, bcc, subject, text, attachmentList);
    }

    /**
     * 检测附件名是否包含扩展名（后缀名）
     * @param attachmentFilename 附件名
     * @return 附件名
     */
    private static String checkAttachmentFilename(String attachmentFilename){
        Assert.isTrue(StrUtil.isNotBlank(FileNameUtil.extName(attachmentFilename)),
                "["+ attachmentFilename +"] Attachment name error, does not include suffix name");
        return attachmentFilename;
    }
}
